<template>
  <div class="boxs">
    <div class="maskLoading" v-if="isLoading">
      <div class="loading">
        <div :style="{ width: loadingWidth + '%' }"></div>
      </div>
      <div style="padding-left: 10px">{{ parseInt(loadingWidth) }}%</div>
    </div>
    <div class="mask">
      <p>x : {{ x }} y:{{ y }} z :{{ z }}</p>
      <button @click="isAutoFun">转动车</button>
      <button @click="stop">停止</button>
      <div class="flex">
        <div @click="setCarColor(index)" v-for="(item, index) in colorAry" :style="{ backgroundColor: item }"
          :key="index"></div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { onMounted, reactive, ref, toRefs } from "vue";
// import {
//   Color,
//   DirectionalLight,
//   HemisphereLight,
//   PerspectiveCamera,
//   Scene,
//   WebGLRenderer,
// } from "three";
import * as THREE from 'three'
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
// import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
// import { ObjectLoader } from "three/examples/jsm/loaders/ObjectLoader";
import { OBJLoader } from "../../public/static/js/OBJLoader";
import { GUI } from 'dat.gui';
const gui = new GUI();
//颜色数组
const colorAry = [
  "rgb(216, 27, 67)",
  "rgb(142, 36, 170)",
  "rgb(81, 45, 168)",
  "rgb(48, 63, 159)",
  "rgb(30, 136, 229)",
  "rgb(0, 137, 123)",
  "rgb(67, 160, 71)",
  "rgb(251, 192, 45)",
  "rgb(245, 124, 0)",
  "rgb(230, 74, 25)",
  "rgb(233, 30, 78)",
  "rgb(156, 39, 176)",
  "rgb(0, 0, 0)",
]; // 颜色数组
// const loader = new GLTFLoader(); //引入模型的loader实例
const loader = new OBJLoader();
const defaultMap = {
  x: 0,
  y: 1,
  z: 10,
}; // 相机的默认坐标
const map = reactive(defaultMap); //把相机坐标设置成可观察对象
const { x, y, z } = toRefs(map); //输出坐标给模板使用
let scene,
  camera,
  renderer,
  controls;
// directionalLight,
// hemisphereLight; // 定义所有three实例变量
let isLoading = ref(true); //是否显示loading  这个load模型监听的进度
let loadingWidth = ref(0); // loading的进度

//创建灯光
const setLight = () => {
  // directionalLight = new THREE.DirectionalLight(0xffffff, 0.9);
  // directionalLight.position.set(-4, 8, 4);
  // hemisphereLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.8);
  // hemisphereLight.position.set(0, 8, 0);
  // scene.add(directionalLight);
  // scene.add(hemisphereLight);


  // // 平行光
  // let lightControls3 = {
  //   x: .9,
  //   y: -3.9,
  //   z: 1.8,
  //   intensity: 4
  // };

  // const light3 = new THREE.DirectionalLight(0xFFFFFF, lightControls3.intensity);
  // light3.width = 30;
  // light3.position.set(lightControls3.x, lightControls3.y, lightControls3.z)
  // const helper = new THREE.DirectionalLightHelper(light3, 1);
  // scene.add(light3);
  // scene.add(helper);

  // const targetObject = new THREE.Object3D();
  // scene.add(targetObject);
  // light3.target = targetObject;


  // const folder3 = gui.addFolder('平行光设置');
  // folder3
  //   .add(lightControls3, 'x', -20, 20, .1)
  //   .name('x:')
  //   .onChange(e => {
  //     light3.position.set(e, lightControls3.y, lightControls3.z);
  //   });
  // folder3
  //   .add(lightControls3, 'y', -20, 20, .1)
  //   .name('y:')
  //   .onChange(e => {
  //     light3.position.set(lightControls3.x, e, lightControls3.z);

  //   });
  // folder3
  //   .add(lightControls3, 'z', -20, 20, .1)
  //   .name('z:')
  //   .onChange(e => {
  //     light3.position.set(lightControls3.x, lightControls3.y, e);

  //   });
  // folder3
  //   .add(lightControls3, 'intensity', 0, 10, 0.1)
  //   .name('intensity:')
  //   .onChange(e => {
  //     light3.intensity = e;
  //   });


  // 环境灯
  let lightControls = {
    intensity: 1,
    color: new THREE.Color('#a59b92')
  };
  const light = new THREE.AmbientLight(lightControls.color, lightControls.intensity); // soft white light
  // light.position.set()
  scene.add(light);
  const folder = gui.addFolder('环境光设置');
  folder
    .add(lightControls, 'intensity', 0, 10, 0.1)
    .name('intensity:')
    .onChange(e => {
      light.intensity = e;
    });
  folder.addColor(lightControls, "color").onChange((e) => {
    light.color.set(new THREE.Color(e))
  });

  // 半球光
  // const light4 = new THREE.HemisphereLight(0x363636, 0x696969, 50);
  // scene.add(light4);



  // // 聚光灯
  // let lightControls = {
  //   x: 1,
  //   y: 3,
  //   z: 1,
  //   intensity: 5
  // };

  // const spotLight = new THREE.SpotLight(0xffffff);
  // spotLight.position.set(lightControls.x, lightControls.y, lightControls.z);
  // spotLight.castShadow = true;
  // spotLight.shadow.mapSize.width = 1024;
  // spotLight.shadow.mapSize.height = 1024;
  // spotLight.shadow.camera.near = 500;
  // spotLight.shadow.camera.far = 4000;
  // spotLight.shadow.camera.fov = 30;
  // const spotLightHelper = new THREE.SpotLightHelper(spotLight);
  // scene.add(spotLightHelper);
  // scene.add(spotLight);
  // const folder = gui.addFolder('光照设置');
  // folder
  //   .add(lightControls, 'x', -20, 20, .1)
  //   .name('x:')
  //   .onChange(e => {
  //     spotLight.position.set(e, lightControls.y, lightControls.z);
  //   });
  // folder
  //   .add(lightControls, 'y', -20, 20, .1)
  //   .name('y:')
  //   .onChange(e => {
  //     spotLight.position.set(lightControls.x, e, lightControls.z);

  //   });
  // folder
  //   .add(lightControls, 'z', -20, 20, .1)
  //   .name('z:')
  //   .onChange(e => {
  //     spotLight.position.set(lightControls.x, lightControls.y, e);

  //   });
  // folder
  //   .add(lightControls, 'intensity', 0, 5, 0.1)
  //   .name('intensity:')
  //   .onChange(e => {
  //     spotLight.intensity = e;
  //   });



  // 点光源
  let lightControls2 = {
    x: 5,
    y: 2,
    z: 0,
    intensity: .2
  };

  const pointLight = new THREE.PointLight(0xffffff, lightControls2.intensity);
  pointLight.position.set(lightControls2.x, lightControls2.y, lightControls2.z);
  scene.add(pointLight);
  const sphereSize = 1;
  const pointLightHelper = new THREE.PointLightHelper(pointLight, sphereSize);
  scene.add(pointLightHelper);

  const folder2 = gui.addFolder('点光源光照设置');
  folder2
    .add(lightControls2, 'x', -100, 100, 1)
    .name('x:')
    .onChange(e => {
      pointLight.position.set(e, lightControls2.y, lightControls2.z);
    });
  folder2
    .add(lightControls2, 'y', -100, 100, 1)
    .name('y:')
    .onChange(e => {
      pointLight.position.set(lightControls2.x, e, lightControls2.z);

    });
  folder2
    .add(lightControls2, 'z', -100, 100, 1)
    .name('z:')
    .onChange(e => {
      pointLight.position.set(lightControls2.x, lightControls2.y, e);

    });
  folder2
    .add(lightControls2, 'intensity', 0, 5, 0.1)
    .name('intensity:')
    .onChange(e => {
      pointLight.intensity = e;
    });
};

// 创建场景
const setScene = () => {
  scene = new THREE.Scene();
  scene.background = new THREE.Color('#d6d8da');
  renderer = new THREE.WebGLRenderer();
  renderer.setSize(innerWidth, innerHeight);
  document.querySelector(".boxs").appendChild(renderer.domElement);
};

// 创建相机
const setCamera = () => {
  /**
         * dat
         */
  let guiControls = {
    near: 0.001,
    far: 100,
    fov: 75,
    ax: 0,
    ay: 0,
    az: 20,
    cpx: 0,
    cpy: 2,
    cpz: 3
  };

  camera = new THREE.PerspectiveCamera(guiControls.fov, window.innerWidth / window.innerHeight, guiControls.near, guiControls.far);
  camera.position.set(guiControls.cpx, guiControls.cpy, guiControls.cpz);
  camera.lookAt(guiControls.ax, guiControls.ay, guiControls.az);

  const helper = new THREE.CameraHelper(camera);
  scene.add(helper);

  const folder = gui.addFolder('相机设置');
  folder
    .add(guiControls, 'near', 0.01, 20, 0.1)
    .name('相机near:')
    .onChange(e => {
      camera.near = e;
      camera.updateProjectionMatrix();
    });
  folder
    .add(guiControls, 'far', 1, 1000, 1)
    .name('相机far:')
    .onChange(e => {
      camera.far = e;
      camera.updateProjectionMatrix();
    });
  folder
    .add(guiControls, 'fov', 50, 150, 1)
    .name('相机fov:')
    .onChange(e => {
      camera.fov = e;
      camera.updateProjectionMatrix();
    });
  folder
    .add(guiControls, 'ax', -50, 50, 0.1)
    .name('相机lookAt _x:')
    .onChange(e => {
      camera.lookAt(e, guiControls.ay, guiControls.az);
    });
  folder
    .add(guiControls, 'ay', -50, 50, 0.1)
    .name('相机lookAt _y:')
    .onChange(e => {
      camera.lookAt(guiControls.ax, e, guiControls.az);
    });
  folder
    .add(guiControls, 'az', -50, 50, 0.1)
    .name('相机lookAt _z:')
    .onChange(e => {
      camera.lookAt(guiControls.ax, guiControls.ay, e);
    });
  folder
    .add(guiControls, 'ax', -50, 50, 0.1)
    .name('相机position _x:')
    .onChange(e => {
      camera.position.set(e, guiControls.ay, guiControls.az);
    });
  folder
    .add(guiControls, 'ay', -50, 50, 0.1)
    .name('相机position _y:')
    .onChange(e => {
      camera.position.set(guiControls.ax, e, guiControls.az);
    });
  folder
    .add(guiControls, 'az', -50, 50, 0.1)
    .name('相机position _z:')
    .onChange(e => {
      camera.position.set(guiControls.ax, guiControls.ay, e);
    });
};

// 设置模型控制
const setControls = () => {
  controls = new OrbitControls(camera, renderer.domElement);
  // controls.maxPolarAngle = (0.9 * Math.PI) / 2;
  controls.enableZoom = true;
  controls.addEventListener("change", render);
};

//返回坐标信息
const render = () => {
  map.x = Number.parseInt(camera.position.x);
  map.y = Number.parseInt(camera.position.y);
  map.z = Number.parseInt(camera.position.z);
};

// 循环场景 、相机、 位置更新
const loop = () => {
  requestAnimationFrame(loop);
  renderer.render(scene, camera);
  controls.update();
};

//是否自动转动
const isAutoFun = () => {
  controls.autoRotate = true;
};
//停止转动
const stop = () => {
  controls.autoRotate = false;
};


//设置颜色
const setCarColor = (index) => {
  const currentColor = new THREE.Color(colorAry[index]);
  scene.traverse((child) => {
    if (child.isMesh) {
      console.log(child.name);
      if (child.name.includes("mesh_0")) {
        child.material.color.set(currentColor);
      }
    }
  });
};

const loadFile = (url) => {
  return new Promise((resolve) => {
    // loader.load(
    //   url,
    //   (gltf) => {
    //     console.log(gltf);
    //     resolve(gltf);
    //   },
    //   ({ loaded, total }) => {
    //     let load = Math.abs((loaded / total) * 100);
    //     loadingWidth.value = load;
    //     if (load >= 100) {
    //       setTimeout(() => {
    //         isLoading.value = false;
    //       }, 1000);
    //     }
    //     console.log((loaded / total) * 100 + "% loaded");
    //   },
    //   (err) => {
    //     reject(err);
    //   }
    // );
    loader.load(url, function (object) {
      // object.rotation.x = 0;
      // object.rotation.y = 0;
      // console.log(object)
      // object.position.x = 2
      // object.position.y = -1
      // scene.add(object);
      object.traverse(function (child) {
        if (child instanceof THREE.Mesh) {
          //设置模型皮肤
          const map = new THREE.TextureLoader().load('/static/3d/wan/d2227041.jpg');
          child.material.map = map;
        }
      });

      console.log('添加完成')
      isLoading.value = false;


      const workObj = new THREE.Object3D();
			workObj.name = '作品';
			workObj.position.set(0, 0.4, 0);
      scene.add(object);
      resolve()
    },
    );

  });
};

/**
     * 设置贴图、颜色
     */
// function setTextrue() {
//   // const textrueGender = url => {
//   //   return new THREE.TextureLoader().load(
//   //     // 由于当前使用的都是本地的贴图所以我们设置成本地的路径
//   //     '/static/3d/wan/' + url,
//   //     (texture) => {
//   //       texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
//   //       texture.offset.set(10, 10);
//   //       texture.isRenderTargetTexture=true;
//   //       // texture.repeat.set(20, 20);
//   //     }
//   //   );
//   // };
//   let texture = {
//     'Plane.005': {
//       zurl: 'd2227041.jpg'
//     },
//     // // 车身颜色
//     // 'Plane005-Mesh_1': {
//     //   zurl: 'te1.jpg'
//     // },
//     // 玻璃颜色
//     glass_rr001_glass_0: {
//       zcolor: '#272727'
//     },
//     // 玻璃颜色
//     boot_bodyshell7_0: {
//       zcolor: 'red'
//     }
//   };

//   scene.traverse(child => {
//     if (child.isMesh) {
//       console.log(child.name);
//       for (const key in texture) {
//         const itemInfo = texture[key];
//         if (key == child.name && itemInfo.zurl) {
//           // 设置贴图
//           // child.material.map = textrueGender(itemInfo.zurl);
//           child.material.map = THREE.ImageUtils.loadTexture('/static/3d/wan/d2227041.jpg');
//           console.log(child.material.map);
//         }
//         if (key == child.name && itemInfo.zcolor) {
//           // 设置颜色
//           child.material.color.set(itemInfo.zcolor);
//         }
//       }
//     }
//   });
// }

//初始化所有函数
const init = async () => {
  setScene();
  setCamera();
  setLight();
  setControls();
  await loadFile("/static/3d/wan/2.obj");
  console.log(11111111111);
  // gltf.scene.scale.set(.1, .1, .1);
  // gltf.position.set(0,0,0)
  // scene.add(gltf);
  // setTextrue();
  loop();
};
//用vue钩子函数调用
onMounted(init);
</script>

<style>
body {
  margin: 0;
  padding: 0;
}

.maskLoading {
  background: rgb(220, 220, 220);
  position: fixed;
  display: flex;
  justify-content: center;
  align-items: center;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  z-index: 1111111;
  color: #fff;
}

.maskLoading .loading {
  width: 400px;
  height: 20px;
  border: 1px solid #fff;
  background: #000;
  overflow: hidden;
  border-radius: 10px;
}

.maskLoading .loading div {
  background: #fff;
  height: 20px;
  width: 0;
  transition-duration: 500ms;
  transition-timing-function: ease-in;
}

canvas {
  width: 100%;
  height: 100%;
  margin: 0;
  position: fixed;
  top: 0;
  left: 0;
}

.mask {
  color: #fff;
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
}

.flex {
  display: flex;
  flex-wrap: wrap;
  padding: 20px;
}

.flex div {
  width: 10px;
  height: 10px;
  margin: 5px;
  cursor: pointer;
}
</style>

